#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "WTSDataDef.hpp"
#include "WTSObject.hpp"
#include <memory>
#include <vector>
#include <thread>
#include <chrono>
#include <cstring>
#include <iostream>
#include <atomic>

using namespace std;
using namespace wtp;

/**
 * @brief WTS数据定义测试类
 * 测试WonderTrader中的核心数据结构定义
 */
class WTSDataDefTest : public ::testing::Test {
protected:
    void SetUp() override {
        // 测试前准备工作
    }

    void TearDown() override {
        // 测试后清理工作
    }
};

/**
 * @brief 测试WTSTickData逐笔行情数据结构
 * 验证逐笔行情数据的基本功能和内存管理
 */
TEST_F(WTSDataDefTest, TestWTSTickData) {
    // 测试基本创建和销毁
    WTSTickData* tick = WTSTickData::create("SHFE.rb2501");
    ASSERT_NE(tick, nullptr);
    
    // 验证基本信息
    EXPECT_STREQ(tick->code(), "SHFE.rb2501");
    
    // 测试基本字段访问（只读方法）
    double price = tick->price();
    double volume = tick->volume();
    uint32_t actiondate = tick->actiondate();
    uint32_t actiontime = tick->actiontime();
    
    // 验证数据类型正确
    EXPECT_GE(price, 0.0);
    EXPECT_GE(volume, 0.0);
    EXPECT_GE(actiondate, 0);
    EXPECT_GE(actiontime, 0);
    
    // 测试买卖盘数据访问
    for(int i = 0; i < 5; i++) {
        double bid_price = tick->bidprice(i);
        double ask_price = tick->askprice(i);
        double bid_qty = tick->bidqty(i);
        double ask_qty = tick->askqty(i);
        
        // 验证数据访问不会崩溃
        EXPECT_TRUE(bid_price >= -1.0);  // -1表示无效数据
        EXPECT_TRUE(ask_price >= -1.0);
        EXPECT_TRUE(bid_qty >= -1.0);
        EXPECT_TRUE(ask_qty >= -1.0);
    }
    
    // 测试边界条件
    EXPECT_EQ(tick->bidprice(-1), -1.0);  // 无效索引
    EXPECT_EQ(tick->bidprice(10), -1.0);  // 超出范围
    EXPECT_EQ(tick->askprice(-1), -1.0);
    EXPECT_EQ(tick->askprice(10), -1.0);
    
    tick->release();
}

/**
 * @brief 测试WTSKlineData K线数据结构
 * 验证K线数据的基本功能和数据完整性
 */
TEST_F(WTSDataDefTest, TestWTSKlineData) {
    // 创建K线数据
    WTSKlineData* kline = WTSKlineData::create("SHFE.rb2501", 100);
    ASSERT_NE(kline, nullptr);
    
    // 验证基本信息
    EXPECT_STREQ(kline->code(), "SHFE.rb2501");
    EXPECT_EQ(kline->size(), 100);  // 预分配大小
    EXPECT_FALSE(kline->IsEmpty());
    
    // 测试周期设置
    kline->setPeriod(KP_Minute1, 1);
    EXPECT_EQ(kline->period(), KP_Minute1);
    EXPECT_EQ(kline->times(), 1);
    
    // 测试闭合状态
    kline->setClosed(true);
    EXPECT_TRUE(kline->isClosed());
    
    kline->setClosed(false);
    EXPECT_FALSE(kline->isClosed());
    
    // 测试Unix时间戳模式
    kline->setUnixTime(true);
    EXPECT_TRUE(kline->isUnixTime());
    
    kline->setUnixTime(false);
    EXPECT_FALSE(kline->isUnixTime());
    
    kline->release();
}

/**
 * @brief 测试WTSValueArray数值数组
 * 验证数值数组的创建、访问和内存管理
 */
TEST_F(WTSDataDefTest, TestWTSValueArray) {
    // 创建数值数组
    WTSValueArray* value_array = WTSValueArray::create();
    ASSERT_NE(value_array, nullptr);
    EXPECT_EQ(value_array->size(), 0);
    EXPECT_TRUE(value_array->empty());
    
    // 测试数据添加
    const int test_count = 10;
    for(int i = 0; i < test_count; i++) {
        value_array->append(i * 1.5);
    }
    
    EXPECT_EQ(value_array->size(), test_count);
    EXPECT_FALSE(value_array->empty());
    
    // 验证数据正确性
    for(int i = 0; i < test_count; i++) {
        EXPECT_DOUBLE_EQ(value_array->at(i), i * 1.5);
        EXPECT_DOUBLE_EQ((*value_array)[i], i * 1.5);  // 测试操作符重载
    }
    
    // 测试数据修改
    value_array->set(0, 999.0);
    EXPECT_DOUBLE_EQ(value_array->at(0), 999.0);
    
    // 测试resize
    value_array->resize(5);
    EXPECT_EQ(value_array->size(), 5);
    
    value_array->release();
}

/**
 * @brief 测试WTSKlineSlice K线数据切片
 * 验证K线数据切片的功能和数据访问
 */
TEST_F(WTSDataDefTest, TestWTSKlineSlice) {
    // 创建K线切片
    WTSKlineSlice* kline_slice = WTSKlineSlice::create("SHFE.rb2501", KP_Minute1, 1, nullptr, 0);
    ASSERT_NE(kline_slice, nullptr);
    
    // 验证基本信息
    EXPECT_EQ(kline_slice->size(), 0);  // 初始为空
    EXPECT_TRUE(kline_slice->empty());
    
    kline_slice->release();
}

/**
 * @brief 测试WTSTickSlice逐笔数据切片
 * 验证逐笔数据切片的功能和数据访问
 */
TEST_F(WTSDataDefTest, TestWTSTickSlice) {
    // 创建逐笔数据切片 - 需要提供数据才能创建
    // 由于create方法要求非空数据，我们只测试空指针情况
    WTSTickSlice* tick_slice = WTSTickSlice::create("SHFE.rb2501", nullptr, 0);
    EXPECT_EQ(tick_slice, nullptr);  // 应该返回NULL因为数据为空
}

/**
 * @brief 测试内存管理和引用计数
 * 验证数据对象的内存管理机制
 */
TEST_F(WTSDataDefTest, TestMemoryManagement) {
    // 测试逐笔数据内存管理
    {
        WTSTickData* tick = WTSTickData::create("TEST.code");
        ASSERT_NE(tick, nullptr);
        
        // 测试引用计数
        tick->retain();
        EXPECT_GT(tick->retainCount(), 1);
        
        tick->release();
        tick->release();  // 最后一次release会销毁对象
    }
    
    // 测试K线数据内存管理
    {
        WTSKlineData* kline = WTSKlineData::create("TEST.code", 10);
        ASSERT_NE(kline, nullptr);
        
        // 测试引用计数
        kline->retain();
        EXPECT_GT(kline->retainCount(), 1);
        
        kline->release();
        kline->release();
    }
    
    // 测试数值数组内存管理
    {
        WTSValueArray* array = WTSValueArray::create();
        ASSERT_NE(array, nullptr);
        
        array->retain();
        EXPECT_GT(array->retainCount(), 1);
        
        array->release();
        array->release();
    }
}

/**
 * @brief 测试边界条件和异常情况
 * 验证数据结构在边界条件下的行为
 */
TEST_F(WTSDataDefTest, TestBoundaryConditions) {
    // 测试空代码创建
    WTSTickData* tick = WTSTickData::create("");
    if (tick != nullptr) {
        EXPECT_STREQ(tick->code(), "");
        tick->release();
    }
    
    // 测试长代码创建
    const char* long_code = "VERY.LONG.CONTRACT.CODE.FOR.TESTING.PURPOSES";
    WTSTickData* tick2 = WTSTickData::create(long_code);
    if (tick2 != nullptr) {
        // 代码可能被截断，但不应该崩溃
        EXPECT_NE(strlen(tick2->code()), 0);
        tick2->release();
    }
    
    // 测试数值数组边界访问
    WTSValueArray* array = WTSValueArray::create();
    if (array != nullptr) {
        array->append(1.0);
        array->append(2.0);
        
        // 测试正常访问
        EXPECT_DOUBLE_EQ(array->at(0), 1.0);
        EXPECT_DOUBLE_EQ(array->at(1), 2.0);
        
        // 测试负索引转换
        EXPECT_DOUBLE_EQ(array->at(-1), 2.0);  // 最后一个元素
        EXPECT_DOUBLE_EQ(array->at(-2), 1.0);  // 倒数第二个元素
        
        array->release();
    }
}

/**
 * @brief 测试数据完整性和一致性
 * 验证数据结构的完整工作流程
 */
TEST_F(WTSDataDefTest, TestCompleteWorkflow) {
    // 创建完整的市场数据工作流程
    
    // 1. 创建逐笔数据
    WTSTickData* tick = WTSTickData::create("SHFE.rb2501");
    ASSERT_NE(tick, nullptr);
    
    // 2. 创建K线数据
    WTSKlineData* kline = WTSKlineData::create("SHFE.rb2501", 100);
    ASSERT_NE(kline, nullptr);
    
    // 3. 创建数据切片
    WTSKlineSlice* slice = WTSKlineSlice::create("SHFE.rb2501", KP_Minute1, 1);
    ASSERT_NE(slice, nullptr);
    
    // 4. 创建数值数组
    WTSValueArray* array = WTSValueArray::create();
    ASSERT_NE(array, nullptr);
    
    // 5. 验证数据一致性
    EXPECT_STREQ(tick->code(), kline->code());
    EXPECT_EQ(kline->period(), KP_Minute1);
    
    // 6. 清理资源
    tick->release();
    kline->release();
    slice->release();
    array->release();
    
    cout << "数据定义完整工作流程测试通过" << endl;
    cout << "合约代码: SHFE.rb2501" << endl;
    cout << "K线周期: 1分钟" << endl;
    cout << "数据对象创建成功" << endl;
}

/**
 * @brief 测试性能特征
 * 验证数据结构的性能表现
 */
TEST_F(WTSDataDefTest, TestPerformanceCharacteristics) {
    const int test_count = 1000;  // 减少测试数量以避免过长时间
    
    // 测试逐笔数据创建性能
    auto start = chrono::high_resolution_clock::now();
    
    vector<WTSTickData*> ticks;
    ticks.reserve(test_count);
    
    for(int i = 0; i < test_count; i++) {
        WTSTickData* tick = WTSTickData::create("TEST.code");
        if (tick != nullptr) {
            ticks.push_back(tick);
        }
    }
    
    auto end = chrono::high_resolution_clock::now();
    auto duration = chrono::duration_cast<chrono::milliseconds>(end - start);
    
    cout << "创建 " << test_count << " 个逐笔数据对象耗时: " << duration.count() << "ms" << endl;
    
    // 测试数据访问性能
    start = chrono::high_resolution_clock::now();
    
    double total_price = 0.0;
    double total_volume = 0.0;
    
    for(auto tick : ticks) {
        total_price += tick->price();
        total_volume += tick->volume();
    }
    
    end = chrono::high_resolution_clock::now();
    auto duration_micro = chrono::duration_cast<chrono::microseconds>(end - start);
    
    cout << "访问 " << test_count << " 个逐笔数据对象耗时: " << duration_micro.count() << "μs" << endl;
    
    // 清理资源
    for(auto tick : ticks) {
        tick->release();
    }
    
    EXPECT_GE(total_price, 0.0);
    EXPECT_GE(total_volume, 0.0);
}

/**
 * @brief 测试多线程安全性
 * 验证数据结构在多线程环境下的表现
 */
TEST_F(WTSDataDefTest, TestThreadSafety) {
    const int thread_count = 4;
    const int operations_per_thread = 100;  // 减少操作数量
    
    vector<thread> threads;
    atomic<int> success_count(0);
    atomic<int> error_count(0);
    
    // 启动多个线程进行数据操作
    for(int t = 0; t < thread_count; t++) {
        threads.emplace_back([&, t]() {
            for(int i = 0; i < operations_per_thread; i++) {
                try {
                    // 创建逐笔数据
                    char code[32];
                    snprintf(code, sizeof(code), "TEST.%d.%d", t, i);
                    WTSTickData* tick = WTSTickData::create(code);
                    if (tick != nullptr) {
                        // 验证数据
                        if (strlen(tick->code()) > 0) {
                            success_count++;
                        }
                        
                        tick->release();
                    }
                } catch (...) {
                    error_count++;
                }
            }
        });
    }
    
    // 等待所有线程完成
    for(auto& t : threads) {
        t.join();
    }
    
    cout << "多线程测试结果: 成功 " << success_count.load() 
         << " 次, 错误 " << error_count.load() << " 次" << endl;
    
    EXPECT_GT(success_count.load(), 0);
    EXPECT_EQ(error_count.load(), 0);
} 